package com.ruoyi.manage.service.impl;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.user.utils.WxJwtUtils;
import com.ruoyi.manage.domain.Avatar;
import com.ruoyi.manage.domain.User;
import com.ruoyi.manage.domain.WxLoginRequest;
import com.ruoyi.manage.domain.WxLoginResult;
import com.ruoyi.manage.mapper.AvatarMapper;
import com.ruoyi.manage.service.IUserService;
import com.ruoyi.manage.service.IWxMiniService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 微信小程序登录服务实现类
 * @author ZhangZhongGen
 */
@Service
public class WxMiniServiceImpl implements IWxMiniService {

    // 微信配置（建议放入application.yml）
    @Value("${wx.mini.appid}")
    private String appid;

    @Value("${wx.mini.secret}")
    private String secret;

    @Autowired
    private IUserService userService;

    @Autowired RestTemplate restTemplate;

    @Autowired
    private AvatarMapper  avatarMapper;

    @Autowired
    private WxJwtUtils wxJwtUtils;

    /**
     * 微信手机号登录
     * @param request 微信登录请求对象，包含小程序传入的code、encryptedData和iv
     * @return 微信登录结果对象，包含若依系统的token和用户信息
     */
    @Override
    public WxLoginResult wxPhoneLogin(WxLoginRequest request) {
        // 1. 获取session_key和openid
        Map<String, String> sessionMap = getWxSession(request.getCode());

        // 2. 解密手机号
        String phoneNumber = decryptData(
                request.getEncryptedData(),
                sessionMap.get("session_key"),
                request.getIv()
        );

        // 3. 处理用户信息
        User user = processUser(sessionMap.get("openid"), phoneNumber);

        // 4. 生成若依token
        String token = wxJwtUtils.generateWxToken(sessionMap.get("openid"));
        return new WxLoginResult(token, user);
    }

    /**
     * 获取微信session_key和openid
     * @param code 小程序传入的code
     * @return 包含openid和session_key的Map
     */
    private Map<String, String> getWxSession(String code) {
        String url = "https://api.weixin.qq.com/sns/jscode2session" +
                "?appid={appid}" +
                "&secret={secret}" +
                "&js_code={code}" +
                "&grant_type=authorization_code";

        Map<String, String> params = new HashMap<>();
        params.put("appid", appid);
        params.put("secret", secret);
        params.put("code", code);
        ResponseEntity<String> response = restTemplate.getForEntity(url, String.class, params);
        JSONObject json = JSON.parseObject(response.getBody());

        if (json.containsKey("errcode")) {
            throw new RuntimeException("微信登录失败: " + json.getString("errmsg"));
        }

        Map<String, String> result = new HashMap<>();
        result.put("openid", json.getString("openid"));
        result.put("session_key", json.getString("session_key"));
        return result;
    }

    /**
     * 解密数据
     * @param encryptedData 加密的数据
     * @param sessionKey session_key
     * @param iv 加密向量
     * @return 解密后的手机号
     */
    private String decryptData(String encryptedData, String sessionKey, String iv) {
        try {
            byte[] data = Base64.getDecoder().decode(encryptedData);
            byte[] key = Base64.getDecoder().decode(sessionKey);
            byte[] ivBytes = Base64.getDecoder().decode(iv);

            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
            IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);

            cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
            byte[] decrypted = cipher.doFinal(data);

            JSONObject json = JSON.parseObject(new String(decrypted));
            return json.getString("phoneNumber");
        } catch (Exception e) {
            throw new RuntimeException("数据解密失败", e);
        }
    }

    /**
     * 处理用户信息
     * @param openid 用户的openid
     * @param phone 用户的手机号
     * @return 处理后的用户对象
     */
    private User processUser(String openid, String phone) {
        // 查询现有用户
        User user = userService.selectUserByOpenid(openid);

        if (user == null) {
            //获取头像集合
            List<Avatar> avatars = avatarMapper.selectAvatarList();
            //随机获取头像
            Avatar avatar = avatars.get((int) (Math.random() * avatars.size()));
            // 创建新用户
            user = User.builder()
                    .openId(openid)
                    .image(avatar.getImage())
                    .userName("WX_" + phone.substring(7, 11))
                    .status(0)
                    .availableTimes(1)
                    .phone(phone)
                    .build();
            userService.insertUser(user);
        } else {
            // 更新手机号（如果需要）
            if (!phone.equals(user.getPhone())) {
                user.setPhone(phone);
                userService.updateUser(user);
            }
        }
        return user;
    }
}
